using System;
using System.Collections.Generic;
using System.Linq;

namespace MT5Trade.Models
{
    /// <summary>
    /// 杠杆控制器 - 基于破产概率的动态杠杆管理
    /// 确保在任何市场条件下破产概率不超过5%
    /// </summary>
    public class LeverageController
    {
        #region 常量定义

        /// <summary>
        /// 目标破产概率阈值 (5%)
        /// </summary>
        public const double TARGET_BANKRUPTCY_THRESHOLD = 0.05;

        /// <summary>
        /// 破产概率预警阈值 (3%)
        /// </summary>
        public const double WARNING_BANKRUPTCY_THRESHOLD = 0.03;

        /// <summary>
        /// 紧急破产概率阈值 (8%)
        /// </summary>
        public const double EMERGENCY_BANKRUPTCY_THRESHOLD = 0.08;

        /// <summary>
        /// 最大杠杆限制
        /// </summary>
        public const double MAX_LEVERAGE_LIMIT = 200.0;

        /// <summary>
        /// 最小杠杆限制
        /// </summary>
        public const double MIN_LEVERAGE_LIMIT = 1.0;

        /// <summary>
        /// 杠杆调整步长 (每次最大调整20%)
        /// </summary>
        public const double LEVERAGE_ADJUSTMENT_STEP = 0.2;

        /// <summary>
        /// 紧急降杠杆比例 (20%)
        /// </summary>
        public const double EMERGENCY_REDUCTION_RATIO = 0.2;

        /// <summary>
        /// 监控间隔 (毫秒)
        /// </summary>
        public const int MONITORING_INTERVAL_MS = 60000; // 1分钟

        #endregion

        #region 数据结构

        /// <summary>
        /// 杠杆控制结果
        /// </summary>
        public class LeverageControlResult
        {
            /// <summary>
            /// 推荐杠杆比例
            /// </summary>
            public double RecommendedLeverage { get; set; }

            /// <summary>
            /// 当前破产概率
            /// </summary>
            public double CurrentBankruptcyProbability { get; set; }

            /// <summary>
            /// 风险级别
            /// </summary>
            public RiskLevel RiskLevel { get; set; }

            /// <summary>
            /// 是否需要立即降杠杆
            /// </summary>
            public bool RequiresImmediateReduction { get; set; }

            /// <summary>
            /// 控制原因说明
            /// </summary>
            public string ControlReason { get; set; } = "";

            /// <summary>
            /// 警告信息列表
            /// </summary>
            public List<string> Warnings { get; set; } = new List<string>();

            /// <summary>
            /// 置信度评分 (0-1)
            /// </summary>
            public double Confidence { get; set; }
        }

        /// <summary>
        /// 杠杆监控报告
        /// </summary>
        public class LeverageMonitoringReport
        {
            /// <summary>
            /// 当前破产概率
            /// </summary>
            public double BankruptcyProbability { get; set; }

            /// <summary>
            /// 安全边际
            /// </summary>
            public double SafetyMargin { get; set; }

            /// <summary>
            /// 风险级别
            /// </summary>
            public RiskLevel RiskLevel { get; set; }

            /// <summary>
            /// 监控状态
            /// </summary>
            public MonitoringStatus Status { get; set; }

            /// <summary>
            /// 推荐行动
            /// </summary>
            public List<string> RecommendedActions { get; set; } = new List<string>();

            /// <summary>
            /// 监控警报
            /// </summary>
            public List<string> Alerts { get; set; } = new List<string>();

            /// <summary>
            /// 风险持续时长 (分钟)
            /// </summary>
            public double RiskDurationMinutes { get; set; }
        }

        /// <summary>
        /// 风险级别枚举
        /// </summary>
        public enum RiskLevel
        {
            Safe = 0,      // 安全 (<1%)
            Low = 1,       // 低风险 (1%-3%)  
            Moderate = 2,  // 中等风险 (3%-5%)
            High = 3,      // 高风险 (5%-8%)
            Critical = 4   // 极高风险 (>8%)
        }

        /// <summary>
        /// 监控状态枚举
        /// </summary>
        public enum MonitoringStatus
        {
            Normal,       // 正常监控
            Warning,      // 预警状态
            Emergency,    // 紧急状态
            Critical      // 危险状态
        }

        #endregion

        #region 私有字段

        private readonly BankruptcyModel _bankruptcyModel;
        private readonly object _lockObject = new object();
        
        // 状态跟踪
        private double _currentLeverage;
        private DateTime _lastControlTime;
        private bool _isInRiskPeriod;
        private readonly Queue<double> _recentBankruptcyProbabilities = new Queue<double>();

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化杠杆控制器
        /// </summary>
        /// <param name="initialLeverage">初始杠杆比例</param>
        public LeverageController(double initialLeverage = 100.0)
        {
            _bankruptcyModel = new BankruptcyModel();
            _currentLeverage = Math.Max(MIN_LEVERAGE_LIMIT, Math.Min(MAX_LEVERAGE_LIMIT, initialLeverage));
            _lastControlTime = DateTime.Now;
            _isInRiskPeriod = false;
        }

        #endregion

        #region 核心杠杆控制方法

        /// <summary>
        /// 控制杠杆比例，确保破产概率不超过目标阈值
        /// </summary>
        /// <param name="expectedReturn">期望收益率</param>
        /// <param name="volatility">市场波动率</param>
        /// <param name="accountCapital">账户资金</param>
        /// <returns>杠杆控制结果</returns>
        public LeverageControlResult ControlLeverage(double expectedReturn, double volatility, double accountCapital)
        {
            // 参数验证
            if (volatility <= 0)
                throw new ArgumentException("波动率必须大于0", nameof(volatility));
            
            if (accountCapital <= 0)
                throw new ArgumentException("账户资金必须大于0", nameof(accountCapital));

            lock (_lockObject)
            {
                var result = new LeverageControlResult();

                // 处理负期望收益的情况
                if (expectedReturn <= 0)
                {
                    result.RecommendedLeverage = MIN_LEVERAGE_LIMIT;
                    result.CurrentBankruptcyProbability = 0.99; // 表示高风险
                    result.RiskLevel = RiskLevel.Critical;
                    result.RequiresImmediateReduction = true;
                    result.ControlReason = "期望收益为负，采用最小杠杆以控制风险";
                    result.Warnings.Add("期望收益率为负，建议停止交易或重新评估策略");
                    result.Confidence = 0.95;
                    
                    UpdateControllerState(result.RecommendedLeverage, result.CurrentBankruptcyProbability);
                    return result;
                }

                try
                {
                    // 1. 计算基于破产概率的杠杆限制
                    double leverageLimit = _bankruptcyModel.CalculateLeverageLimit(
                        expectedReturn, volatility, TARGET_BANKRUPTCY_THRESHOLD);

                    // 2. 计算基于波动率环境的杠杆调整
                    double environmentLeverage = _bankruptcyModel.AdjustLeverageByVolatilityEnvironment(
                        volatility, leverageLimit);

                    // 3. 使用更保守的杠杆限制，确保破产概率约束
                    double safeLeverage = Math.Min(leverageLimit, environmentLeverage);
                    safeLeverage = Math.Max(MIN_LEVERAGE_LIMIT, Math.Min(MAX_LEVERAGE_LIMIT, safeLeverage));

                    // 4. 应用逐步调整限制，避免剧烈变化
                    double maxAdjustment = _currentLeverage * LEVERAGE_ADJUSTMENT_STEP;
                    double leverageDifference = safeLeverage - _currentLeverage;
                    
                    if (Math.Abs(leverageDifference) > maxAdjustment)
                    {
                        // 限制调整幅度
                        if (leverageDifference > 0)
                        {
                            safeLeverage = _currentLeverage + maxAdjustment;
                        }
                        else
                        {
                            safeLeverage = _currentLeverage - maxAdjustment;
                        }
                    }

                    // 5. 设置推荐杠杆（确保不超过破产概率约束的杠杆限制）
                    result.RecommendedLeverage = Math.Min(safeLeverage, leverageLimit);

                    // 6. 基于最终推荐杠杆计算实际破产概率
                    double bankruptcyProbability;
                    try
                    {
                        bankruptcyProbability = _bankruptcyModel.CalculateContinuousBankruptcyProbability(
                            expectedReturn, volatility, result.RecommendedLeverage, accountCapital);
                    }
                    catch (ArgumentException)
                    {
                        // 如果计算失败，强制使用最小杠杆
                        result.RecommendedLeverage = MIN_LEVERAGE_LIMIT;
                        bankruptcyProbability = 1.0;
                    }

                    result.CurrentBankruptcyProbability = bankruptcyProbability;
                    
                    // 7. 评估风险级别
                    result.RiskLevel = AssessRiskLevel(bankruptcyProbability, volatility);

                    // 8. 最后检查：如果破产概率仍然超过阈值，强制使用最小杠杆
                    if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
                    {
                        result.RecommendedLeverage = MIN_LEVERAGE_LIMIT;
                        result.RequiresImmediateReduction = true;
                        
                        // 重新计算基于最小杠杆的破产概率
                        try
                        {
                            result.CurrentBankruptcyProbability = _bankruptcyModel.CalculateContinuousBankruptcyProbability(
                                expectedReturn, volatility, MIN_LEVERAGE_LIMIT, accountCapital);
                        }
                        catch (ArgumentException)
                        {
                            result.CurrentBankruptcyProbability = 0.0; // 最小杠杆应该是安全的
                        }
                        result.RiskLevel = AssessRiskLevel(result.CurrentBankruptcyProbability, volatility);
                    }

                    // 9. 生成控制原因和警告
                    result.ControlReason = GenerateControlReason(result.RecommendedLeverage, leverageLimit, 
                        environmentLeverage, result.RiskLevel);
                    result.Warnings = GenerateWarnings(result.RiskLevel, result.CurrentBankruptcyProbability, volatility);

                    // 10. 计算置信度
                    result.Confidence = CalculateConfidence(result.RiskLevel, volatility, expectedReturn);

                    // 11. 更新内部状态
                    UpdateControllerState(result.RecommendedLeverage, result.CurrentBankruptcyProbability);

                    return result;
                }
                catch (Exception ex)
                {
                    // 异常处理：返回保守的杠杆建议
                    result.RecommendedLeverage = MIN_LEVERAGE_LIMIT;
                    result.CurrentBankruptcyProbability = 1.0;
                    result.RiskLevel = RiskLevel.Critical;
                    result.RequiresImmediateReduction = true;
                    result.ControlReason = $"计算过程中发生异常，采用最小杠杆：{ex.Message}";
                    result.Warnings.Add("杠杆计算异常，请检查输入参数");
                    result.Confidence = 0.1;
                    
                    UpdateControllerState(result.RecommendedLeverage, result.CurrentBankruptcyProbability);
                    return result;
                }
            }
        }

        /// <summary>
        /// 监控杠杆风险状态
        /// </summary>
        /// <param name="expectedReturn">期望收益率</param>
        /// <param name="volatility">市场波动率</param>
        /// <param name="accountCapital">账户资金</param>
        /// <returns>杠杆监控报告</returns>
        public LeverageMonitoringReport MonitorLeverageRisk(double expectedReturn, double volatility, double accountCapital)
        {
            lock (_lockObject)
            {
                var report = new LeverageMonitoringReport();

                try
                {
                    // 计算当前破产概率
                    if (expectedReturn > 0)
                    {
                        report.BankruptcyProbability = _bankruptcyModel.CalculateContinuousBankruptcyProbability(
                            expectedReturn, volatility, _currentLeverage, accountCapital);
                    }
                    else
                    {
                        report.BankruptcyProbability = 0.99; // 负期望收益视为高风险
                    }

                    // 计算安全边际
                    report.SafetyMargin = Math.Max(0, TARGET_BANKRUPTCY_THRESHOLD - report.BankruptcyProbability);

                    // 评估风险级别
                    report.RiskLevel = AssessRiskLevel(report.BankruptcyProbability, volatility);

                    // 确定监控状态
                    report.Status = DetermineMonitoringStatus(report.BankruptcyProbability);

                    // 生成推荐行动
                    report.RecommendedActions = GenerateRecommendedActions(report.BankruptcyProbability, report.RiskLevel);

                    // 生成监控警报
                    report.Alerts = GenerateMonitoringAlerts(report.BankruptcyProbability, volatility);

                    // 计算风险持续时长
                    report.RiskDurationMinutes = CalculateRiskDuration();

                    // 记录破产概率历史
                    RecordBankruptcyProbability(report.BankruptcyProbability);
                }
                catch (Exception)
                {
                    // 异常时设置为最高风险状态
                    report.BankruptcyProbability = 1.0;
                    report.SafetyMargin = 0.0;
                    report.RiskLevel = RiskLevel.Critical;
                    report.Status = MonitoringStatus.Critical;
                    report.RecommendedActions.Add("系统异常，立即降低杠杆至最小值");
                    report.Alerts.Add("监控系统发生异常");
                    report.RiskDurationMinutes = 0;
                }

                return report;
            }
        }

        /// <summary>
        /// 紧急降杠杆
        /// </summary>
        /// <returns>降杠杆后的新杠杆比例</returns>
        public double EmergencyLeverageReduction()
        {
            lock (_lockObject)
            {
                double newLeverage = _currentLeverage * (1.0 - EMERGENCY_REDUCTION_RATIO);
                _currentLeverage = Math.Max(MIN_LEVERAGE_LIMIT, newLeverage);
                _lastControlTime = DateTime.Now;
                _isInRiskPeriod = true;

                return _currentLeverage;
            }
        }

        #endregion

        #region 私有辅助方法

        /// <summary>
        /// 评估风险级别
        /// </summary>
        private RiskLevel AssessRiskLevel(double bankruptcyProbability, double volatility)
        {
            if (bankruptcyProbability <= 0.01) return RiskLevel.Safe;
            if (bankruptcyProbability <= 0.03) return RiskLevel.Low;
            if (bankruptcyProbability <= TARGET_BANKRUPTCY_THRESHOLD) return RiskLevel.Moderate;
            if (bankruptcyProbability <= EMERGENCY_BANKRUPTCY_THRESHOLD) return RiskLevel.High;
            return RiskLevel.Critical;
        }

        /// <summary>
        /// 确定最终杠杆建议
        /// </summary>
        private double DetermineFinalLeverage(double proposedLeverage, double bankruptcyProbability, LeverageControlResult result)
        {
            // 如果破产概率超过目标阈值，强制使用最小杠杆
            if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
            {
                result.RequiresImmediateReduction = true;
                return MIN_LEVERAGE_LIMIT;
            }

            // 如果破产概率在预警范围内，谨慎调整
            if (bankruptcyProbability > WARNING_BANKRUPTCY_THRESHOLD)
            {
                return Math.Min(proposedLeverage, _currentLeverage); // 不增加杠杆
            }

            // 正常情况下的杠杆调整
            double maxAdjustment = _currentLeverage * LEVERAGE_ADJUSTMENT_STEP;
            double leverageDifference = proposedLeverage - _currentLeverage;
            
            if (Math.Abs(leverageDifference) > maxAdjustment)
            {
                // 限制调整幅度
                if (leverageDifference > 0)
                {
                    return _currentLeverage + maxAdjustment;
                }
                else
                {
                    return _currentLeverage - maxAdjustment;
                }
            }

            return proposedLeverage;
        }

        /// <summary>
        /// 生成控制原因说明
        /// </summary>
        private string GenerateControlReason(double recommendedLeverage, double leverageLimit, 
            double environmentLeverage, RiskLevel riskLevel)
        {
            if (recommendedLeverage == MIN_LEVERAGE_LIMIT)
            {
                return $"风险级别{riskLevel}，使用最小杠杆{MIN_LEVERAGE_LIMIT:F1}x以确保资金安全";
            }

            if (Math.Abs(recommendedLeverage - leverageLimit) < 0.01)
            {
                return $"基于破产概率约束，推荐杠杆{recommendedLeverage:F1}x";
            }

            if (Math.Abs(recommendedLeverage - environmentLeverage) < 0.01)
            {
                return $"基于市场波动环境调整，推荐杠杆{recommendedLeverage:F1}x";
            }

            return $"综合风险评估后推荐杠杆{recommendedLeverage:F1}x";
        }

        /// <summary>
        /// 生成警告信息
        /// </summary>
        private List<string> GenerateWarnings(RiskLevel riskLevel, double bankruptcyProbability, double volatility)
        {
            var warnings = new List<string>();

            if (riskLevel >= RiskLevel.High)
            {
                warnings.Add($"破产概率{bankruptcyProbability:P2}较高，建议降低杠杆");
            }

            if (volatility > BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
            {
                warnings.Add($"市场波动率{volatility:P2}较高，注意风险控制");
            }

            if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
            {
                warnings.Add("破产概率已超过5%目标阈值，需要立即行动");
            }

            return warnings;
        }

        /// <summary>
        /// 计算置信度
        /// </summary>
        private double CalculateConfidence(RiskLevel riskLevel, double volatility, double expectedReturn)
        {
            double baseConfidence = 0.8;
            
            // 基于风险级别调整
            switch (riskLevel)
            {
                case RiskLevel.Safe:
                    baseConfidence = 0.95;
                    break;
                case RiskLevel.Low:
                    baseConfidence = 0.85;
                    break;
                case RiskLevel.Moderate:
                    baseConfidence = 0.75;
                    break;
                case RiskLevel.High:
                    baseConfidence = 0.60;
                    break;
                case RiskLevel.Critical:
                    baseConfidence = 0.40;
                    break;
            }

            // 基于波动率调整
            if (volatility > BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
            {
                baseConfidence *= 0.9; // 高波动降低置信度
            }

            // 基于期望收益调整
            if (expectedReturn <= 0)
            {
                baseConfidence *= 0.5; // 负期望收益大幅降低置信度
            }

            return Math.Max(0.1, Math.Min(1.0, baseConfidence));
        }

        /// <summary>
        /// 更新控制器内部状态
        /// </summary>
        private void UpdateControllerState(double newLeverage, double bankruptcyProbability)
        {
            _currentLeverage = newLeverage;
            _lastControlTime = DateTime.Now;
            _isInRiskPeriod = bankruptcyProbability > WARNING_BANKRUPTCY_THRESHOLD;
        }

        /// <summary>
        /// 确定监控状态
        /// </summary>
        private MonitoringStatus DetermineMonitoringStatus(double bankruptcyProbability)
        {
            if (bankruptcyProbability > EMERGENCY_BANKRUPTCY_THRESHOLD)
                return MonitoringStatus.Critical;
            if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
                return MonitoringStatus.Emergency;
            if (bankruptcyProbability > WARNING_BANKRUPTCY_THRESHOLD)
                return MonitoringStatus.Warning;
            return MonitoringStatus.Normal;
        }

        /// <summary>
        /// 生成推荐行动
        /// </summary>
        private List<string> GenerateRecommendedActions(double bankruptcyProbability, RiskLevel riskLevel)
        {
            var actions = new List<string>();

            if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
            {
                actions.Add("立即降低杠杆至安全水平");
                actions.Add("暂停开新仓位");
            }
            else if (bankruptcyProbability > WARNING_BANKRUPTCY_THRESHOLD)
            {
                actions.Add("考虑适度降低杠杆");
                actions.Add("加强风险监控频率");
            }
            else
            {
                actions.Add("维持当前杠杆水平");
                actions.Add("继续正常交易");
            }

            return actions;
        }

        /// <summary>
        /// 生成监控警报
        /// </summary>
        private List<string> GenerateMonitoringAlerts(double bankruptcyProbability, double volatility)
        {
            var alerts = new List<string>();

            if (bankruptcyProbability > EMERGENCY_BANKRUPTCY_THRESHOLD)
            {
                alerts.Add($"严重警告：破产概率{bankruptcyProbability:P2}超过紧急阈值");
            }
            else if (bankruptcyProbability > TARGET_BANKRUPTCY_THRESHOLD)
            {
                alerts.Add($"风险警告：破产概率{bankruptcyProbability:P2}超过目标阈值");
            }

            if (volatility > BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
            {
                alerts.Add($"市场警告：波动率{volatility:P2}处于高水平");
            }

            return alerts;
        }

        /// <summary>
        /// 计算风险持续时长
        /// </summary>
        private double CalculateRiskDuration()
        {
            if (!_isInRiskPeriod)
                return 0.0;

            return (DateTime.Now - _lastControlTime).TotalMinutes;
        }

        /// <summary>
        /// 记录破产概率历史
        /// </summary>
        private void RecordBankruptcyProbability(double bankruptcyProbability)
        {
            _recentBankruptcyProbabilities.Enqueue(bankruptcyProbability);
            
            // 保留最近10条记录
            while (_recentBankruptcyProbabilities.Count > 10)
            {
                _recentBankruptcyProbabilities.Dequeue();
            }
        }

        #endregion

        #region 公用工具方法

        /// <summary>
        /// 获取当前杠杆比例
        /// </summary>
        public double GetCurrentLeverage()
        {
            lock (_lockObject)
            {
                return _currentLeverage;
            }
        }

        /// <summary>
        /// 设置杠杆比例（带限制检查）
        /// </summary>
        /// <param name="leverage">目标杠杆比例</param>
        /// <returns>实际设置的杠杆比例</returns>
        public double SetLeverage(double leverage)
        {
            lock (_lockObject)
            {
                _currentLeverage = Math.Max(MIN_LEVERAGE_LIMIT, Math.Min(MAX_LEVERAGE_LIMIT, leverage));
                return _currentLeverage;
            }
        }

        /// <summary>
        /// 获取控制器状态信息
        /// </summary>
        /// <returns>状态描述字符串</returns>
        public string GetControllerStatus()
        {
            lock (_lockObject)
            {
                var avgBankruptcyProb = _recentBankruptcyProbabilities.Count > 0 
                    ? _recentBankruptcyProbabilities.Average() 
                    : 0.0;

                return $"杠杆控制器状态 - " +
                       $"当前杠杆: {_currentLeverage:F1}x, " +
                       $"风险状态: {(_isInRiskPeriod ? "高风险" : "正常")}, " +
                       $"平均破产概率: {avgBankruptcyProb:P2}, " +
                       $"最后控制时间: {_lastControlTime:HH:mm:ss}, " +
                       $"历史记录: {_recentBankruptcyProbabilities.Count}条";
            }
        }

        /// <summary>
        /// 重置控制器状态
        /// </summary>
        /// <param name="initialLeverage">重置后的初始杠杆</param>
        public void ResetController(double initialLeverage = 100.0)
        {
            lock (_lockObject)
            {
                _currentLeverage = Math.Max(MIN_LEVERAGE_LIMIT, 
                    Math.Min(MAX_LEVERAGE_LIMIT, initialLeverage));
                _lastControlTime = DateTime.Now;
                _isInRiskPeriod = false;
                _recentBankruptcyProbabilities.Clear();
            }
        }

        #endregion
    }
}
